<div class="content-section introduction">
    <div class="feature-intro">
        <h1>Listbox</h1>
        <p>Listbox is used to select one or more values from a list of items.</p>
    </div>
    <app-demoActions github="listbox" stackblitz="listbox-demo"></app-demoActions>
</div>

<div class="content-section implementation">
    <div class="card">
        <h5>Single</h5>
        <p-listbox [options]="cities" [(ngModel)]="selectedCity" optionLabel="name" [style]="{'width':'15rem'}"></p-listbox>
        
        <h5>Advanced with Templating, Filtering and Multiple Selection</h5>
        <p-listbox [options]="countries" [(ngModel)]="selectedCountries" [metaKeySelection]="false" [checkbox]="true" [filter]="true" [multiple]="true" optionLabel="name" [listStyle]="{'max-height':'250px'}" [style]="{'width':'15rem'}">
            <ng-template let-country pTemplate="item">
                <div class="country-item">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" />
                    <div>{{country.name}}</div>
                </div>
            </ng-template>
        </p-listbox>

        <h5>Advanced with Group, Filtering and Multiple Selection</h5>
        <p-listbox [options]="groupedCities" [group]="true" [(ngModel)]="selectedCities" [metaKeySelection]="false" [checkbox]="true" [filter]="true" [multiple]="true" [listStyle]="{'max-height':'250px'}" [style]="{'width':'15rem'}">
            <ng-template let-group pTemplate="group">
                <div class="flex align-items-center">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'mr-2 flag flag-' + group.value" style="width: 20px"/>
                    <span>{{group.label}}</span>
                </div>
            </ng-template>
        </p-listbox>
    </div>
</div>

<div class="content-section documentation">
  <p-tabView>
    <p-tabPanel header="Documentation">
      <h5>Import</h5>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;ListboxModule&#125; from 'primeng/listbox';
</app-code>


        <h5>Getting Started</h5>
        <p>Listbox requires a value to bind and a collection of options.</p>
      
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCity" optionLabel="name"&gt;&lt;/p-listbox&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
interface City &#123;
    name: string,
    code: string
&#125;

export class ListboxDemo &#123;

    cities: City[];

    selectedCity: City;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

        <h5>Value Binding</h5>
        <p>The option itself is bound to the model by default, use <i>optionValue</i> to customize the property to pass as the value.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCityCode" optionLabel="name" optionValue="code"&gt;&lt;/p-listbox&gt;
</app-code>
    
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
interface City &#123;
    name: string,
    code: string
&#125;

export class ListboxDemo &#123;

    cities: City[];

    selectedCityCode: string;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

      <h5>Selection</h5>
      <p>Listbox allows selection of either single or multiple items whereas <i>checkbox</i> option displays a checkbox to indicate multiple selection.
        In single case, model should be a single object reference whereas in multiple case should be an array. Multiple items can either be selected
        using metaKey or toggled individually depending on the value of <i>metaKeySelection</i> property value which is true by default. On touch enabled
        devices metaKeySelection is turned off automatically.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCities" [multiple]="true" optionLabel="name"&gt;&lt;/p-listbox&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class ListboxDemo &#123;

    cities: City[];

    selectedCities: City[];

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

        <h5>Disabled Options</h5>
        <p>Particular options can be prevented from selection using the <i>optionDisabled</i> property.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCity" optionLabel="name" optionDisabled="inactive"&gt;&lt;/p-listbox&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class ListboxDemo &#123;

    cities: City[];

    selectedCity: City;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY', inactive: false&#125;,
            &#123;name: 'Rome', code: 'RM', inactive: true&#125;,
            &#123;name: 'London', code: 'LDN', inactive: false&#125;,
            &#123;name: 'Istanbul', code: 'IST', inactive: true&#125;,
            &#123;name: 'Paris', code: 'PRS', inactive: false&#125;
        ];
    &#125;

&#125;
</app-code>

      <h5>Filter</h5>
      <p>Filtering allows searching items in the list using an input field at the header. In order to use filtering, set <i>filter</i> property as true. Default filtering
        mode is "contains" and alternatives are available via the <i>filterMatchMode</i> property. See property documentation for more information.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCity" [filter]="true"&gt;&lt;/p-listbox&gt;
</app-code>

      <h5>Model Driven Forms</h5>
      <p>Listbox can be used in a model driven form as well.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="cities" formControlName="selectedCity"&gt;&lt;/p-listbox&gt;
</app-code>

      <h5>Custom Content</h5>
      <p>For custom content support define a ng-template named <i>item</i> where the local ng-template variable refers to an option in the options collection. Additionally a custom header and footer can be provided
        using <i>header</i>, <i>filter</i> and <i>footer</i> templates. In addition when grouping is enabled, <i>group</i> template is available
        to customize the option groups. All templates get the option instance as the default local template variable.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-listbox [options]="countries" [(ngModel)]="selectedCountries" [multiple]="true" optionLabel="name" filterBy="label" [listStyle]="&#123;'max-height':'250px'&#125;"&gt;
    &lt;ng-template pTemplate="header"&gt;
        Header Content
    &lt;/ng-template&gt;
    &lt;ng-template pTemplate="filter" let-options="options"&gt;
        &lt;div class="p-inputgroup"&gt;
            &lt;span class="p-inputgroup-addon"&gt;&lt;i class="pi pi-search"&gt;&lt;/i&gt;&lt;/span&gt;
            &lt;input type="text" pInputText placeholder="Filter" [(ngModel)]="filterValue" (keyup)="options.filter($event)"&gt;
        &lt;/div&gt;
        &lt;button pButton icon="pi pi-times" class="ml-3" (click)="myResetFunction(options)"&gt;&lt;/button&gt;
    &lt;/ng-template&gt;
    &lt;ng-template let-country pTemplate="item"&gt;
        &lt;div class="country-item"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;country.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
    &lt;ng-template pTemplate="footer"&gt;
        Footer Content
    &lt;/ng-template&gt;
&lt;/p-listbox&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;ListboxFilterOptions&#125; from 'primeng/listbox';
...
interface Country &#123;
    name: string,
    code: string
&#125;

export class ListboxDemo &#123;

    countries: Country[];

    selectedCountries: Country[];

    filterValue = '';

    constructor() &#123;
        this.countries = [
            &#123;name: 'Australia', code: 'AU'&#125;,
            &#123;name: 'Brazil', code: 'BR'&#125;,
            &#123;name: 'China', code: 'CN'&#125;,
            &#123;name: 'Egypt', code: 'EG'&#125;,
            &#123;name: 'France', code: 'FR'&#125;,
            &#123;name: 'Germany', code: 'DE'&#125;,
            &#123;name: 'India', code: 'IN'&#125;,
            &#123;name: 'Japan', code: 'JP'&#125;,
            &#123;name: 'Spain', code: 'ES'&#125;,
            &#123;name: 'United States', code: 'US'&#125;
        ];
    &#125;
    
    myResetFunction(options: MultiSelectFilterOptions) &#123;
        options.reset();
        this.filterValue = '';
    &#125;

&#125;
</app-code>


    <h5>Properties</h5>
    <div class="doc-tablewrapper">
        <table class="doc-table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Type</th>
                    <th>Default</th>
                    <th>Description</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>ariaFilterLabel</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Defines a string that labels the filter input.</td>
                </tr>
                <tr>
                    <td>checkbox</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>When specified, allows selecting items with checkboxes.</td>
                </tr>
                <tr>
                    <td>dataKey</td>
                    <td>string</td>
                    <td>null</td>
                    <td>A property to uniquely identify a value in options.</td>
                </tr>
                <tr>
                    <td>disabled</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>When present, it specifies that the element should be disabled.</td>
                </tr>
                <tr>
                    <td>filter</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>When specified, displays a filter input at header.</td>
                </tr>
                <tr>
                    <td>filterMatchMode</td>
                    <td>string</td>
                    <td>contains</td>
                    <td>Defines how the items are filtered, valid values are "contains" (default) "startsWith", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt" and "gte".</td>
                </tr>
                <tr>
                    <td>filterValue</td>
                    <td>string</td>
                    <td>null</td>
                    <td>When specified, filter displays with this value.</td>
                </tr>
                <tr>
                    <td>filterLocale</td>
                    <td>string</td>
                    <td>undefined</td>
                    <td>Locale to use in filtering. The default locale is the host environment's current locale.</td>
                </tr>
                <tr>
                    <td>filterBy</td>
                    <td>string</td>
                    <td>null</td>
                    <td>When filtering is enabled, filterBy decides which field or fields (comma separated) to search against.</td>
                </tr>
                <tr>
                    <td>filterPlaceHolder</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Defines placeholder of the filter input.</td>
                </tr>
                <tr>
                    <td>emptyFilterMessage</td>
                    <td>string</td>
                    <td>No results found</td>
                    <td>Text to display when filtering does not return any results.</td>
                </tr>
                <tr>
                    <td>listStyle</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Inline style of the list element.</td>
                </tr>
                <tr>
                    <td>listStyleClass</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Style class of the list element.</td>
                </tr>
                <tr>
                    <td>metaKeySelection</td>
                    <td>boolean</td>
                    <td>true</td>
                    <td>Defines how multiple items can be selected, when true metaKey needs to be pressed to select or
                        unselect an item and when set to false selection of each item
                        can be toggled individually. On touch enabled devices, metaKeySelection is turned off
                        automatically.</td>
                </tr>
                <tr>
                    <td>multiple</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>When specified, allows selecting multiple values.</td>
                </tr>
                <tr>
                    <td>readonly</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>When present, it specifies that the element value cannot be changed.</td>
                </tr>
                <tr>
                    <td>emptyMessage</td>
                    <td>string</td>
                    <td>No records found.</td>
                    <td>Text to display when there is no data. Defaults to global value in i18n translation configuration.</td>
                </tr>
                <tr>
                    <td>emptyFilterMessage</td>
                    <td>string</td>
                    <td>No results found</td>
                    <td>Text to display when filtering does not return any results. Defaults to global value in i18n translation configuration.</td>
                </tr>
                <tr>
                    <td>options</td>
                    <td>array</td>
                    <td>null</td>
                    <td>An array of selectitems to display as the available options.</td>
                </tr>
                <tr>
                    <td>optionLabel</td>
                    <td>string</td>
                    <td>label</td>
                    <td>Name of the label field of an option.</td>
                </tr>
                <tr>
                    <td>optionValue</td>
                    <td>string</td>
                    <td>value</td>
                    <td>Name of the value field of an option.</td>
                </tr>
                <tr>
                    <td>optionDisabled</td>
                    <td>string</td>
                    <td>disabled</td>
                    <td>Name of the disabled field of an option.</td>
                </tr>
                <tr>
                    <td>optionGroupLabel</td>
                    <td>string</td>
                    <td>label</td>
                    <td>Name of the label field of an option group.</td>
                </tr>
                <tr>
                    <td>optionGroupChildren</td>
                    <td>string</td>
                    <td>items</td>
                    <td>Name of the options field of an option group.</td>
                </tr>
                <tr>
                    <td>group</td>
                    <td>boolean</td>
                    <td>false</td>
                    <td>Whether to display options as grouped when nested options are provided.</td>
                </tr>
                <tr>
                    <td>showToggleAll</td>
                    <td>boolean</td>
                    <td>true</td>
                    <td>Whether header checkbox is shown in multiple mode.</td>
                </tr>
                <tr>
                    <td>style</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Inline style of the container.</td>
                </tr>
                <tr>
                    <td>styleClass</td>
                    <td>string</td>
                    <td>null</td>
                    <td>Style class of the container.</td>
                </tr>
            </tbody>
        </table>
    </div>

    <h5>Events</h5>
    <div class="doc-tablewrapper">
        <table class="doc-table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Parameters</th>
                    <th>Description</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>onChange</td>
                    <td>event.originalEvent: browser event<br />
                        event.value: single value or an array of values that are selected
                    </td>
                    <td>Callback to invoke when value of listbox changes.</td>
                </tr>
                <tr>
                    <td>onDblClick</td>
                    <td>event.originalEvent: browser event<br />
                        event.value: single value or an array of values that are selected
                        event.option: option that are clicked
                    </td>
                    <td>Callback to invoke when an item is double clicked.</td>
                </tr>
                <tr>
                    <td>onClick</td>
                    <td>event.originalEvent: browser event<br />
                        event.value: single value or an array of values that are selected
                        event.option: option that are clicked
                    </td>
                    <td>Callback to invoke when listbox option clicks.</td>
                </tr>
            </tbody>
        </table>
    </div>

    <h5>Templates</h5>
    <div class="doc-tablewrapper">
        <table class="doc-table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Parameters</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>item</td>
                    <td>$implicit: Data of the option <br />
                        index: Index of the option</td>
                </tr>
                <tr>
                    <td>group</td>
                    <td>$implicit: Group option</td>
                </tr>
                <tr>
                    <td>header</td>
                    <td>-</td>
                </tr>
                <tr>
                    <td>filter</td>
                    <td>options.filter: Callback to filter data by the value param<br />
                        options.reset: Resets the filter.
                    </td>
                </tr>
                <tr>
                    <td>empty</td>
                    <td>-</td>
                </tr>
                <tr>
                    <td>emptyfilter</td>
                    <td>-</td>
                </tr>
                <tr>
                    <td>footer</td>
                    <td>-</td>
                </tr>
            </tbody>
        </table>
    </div>

    <h5>Styling</h5>
    <p>Following is the list of structural style classes, for theming classes visit <a href="#" [routerLink]="['/theming']">theming
            page</a>.</p>
    <div class="doc-tablewrapper">
        <table class="doc-table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Element</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>p-listbox</td>
                    <td>Container element.</td>
                </tr>
                <tr>
                    <td>p-listbox-list</td>
                    <td>List container.</td>
                </tr>
                <tr>
                    <td>p-listbox-item</td>
                    <td>An item in the list.</td>
                </tr>
                <tr>
                    <td>p-listbox-header</td>
                    <td>Header element.</td>
                </tr>
                <tr>
                    <td>p-listbox-filter-container</td>
                    <td>Container of filter input in header.</td>
                </tr>
            </tbody>
        </table>
    </div>

    <h5>Dependencies</h5>
    <p>None.</p>
    </p-tabPanel>

    <p-tabPanel header="Source">
      <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/listbox" class="btn-viewsource" target="_blank">
        <span>View on GitHub</span>
      </a>
      <a href="https://stackblitz.com/edit/primeng-listbox-demo" class="btn-viewsource" style="margin-left: .5em;" target="_blank">
        <span>Edit in StackBlitz</span>
      </a>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;h5&gt;Single&lt;/h5&gt;
&lt;p-listbox [options]="cities" [(ngModel)]="selectedCity" optionLabel="name" [style]="&#123;'width':'15rem'&#125;"&gt;&lt;/p-listbox&gt;

&lt;h5&gt;Advanced with Templating, Filtering and Multiple Selection&lt;/h5&gt;
&lt;p-listbox [options]="countries" [(ngModel)]="selectedCountries" [metaKeySelection]="false" [checkbox]="true" [filter]="true" [multiple]="true" optionLabel="name" [listStyle]="&#123;'max-height':'250px'&#125;" [style]="&#123;'width':'15rem'&#125;"&gt;
    &lt;ng-template let-country pTemplate="item"&gt;
        &lt;div class="country-item"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;country.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-listbox&gt;

&lt;h5&gt;Advanced with Group, Filtering and Multiple Selection&lt;/h5&gt;
&lt;p-listbox [options]="groupedCities" [group]="true" [(ngModel)]="selectedCountries" [metaKeySelection]="false" [checkbox]="true" [filter]="true" [multiple]="true" [listStyle]="&#123;'max-height':'250px'&#125;" [style]="&#123;'width':'15rem'&#125;"&gt;
    &lt;ng-template let-group pTemplate="group"&gt;
        &lt;div class="flex align-items-center"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'mr-2 flag flag-' + group.value" style="width: 20px"/&gt;
            &lt;span&gt;&#123;&#123;group.label&#125;&#125;&lt;/span&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-listbox&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;Component&#125; from '@angular/core';
import &#123; SelectItemGroup &#125; from 'primeng/api';

interface City &#123;
    name: string,
    code: string
&#125;

interface Country &#123;
    name: string,
    code: string
&#125;

@Component(&#123;
    templateUrl: './listboxdemo.html'
&#125;)
export class ListboxDemo &#123;

    groupedCities: SelectItemGroup[];
    
    cities: City[];

    countries: Country[];

    selectedCity: City;

    selectedCountries: Country[];

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];

        this.countries = [
            &#123;name: 'Australia', code: 'AU'&#125;,
            &#123;name: 'Brazil', code: 'BR'&#125;,
            &#123;name: 'China', code: 'CN'&#125;,
            &#123;name: 'Egypt', code: 'EG'&#125;,
            &#123;name: 'France', code: 'FR'&#125;,
            &#123;name: 'Germany', code: 'DE'&#125;,
            &#123;name: 'India', code: 'IN'&#125;,
            &#123;name: 'Japan', code: 'JP'&#125;,
            &#123;name: 'Spain', code: 'ES'&#125;,
            &#123;name: 'United States', code: 'US'&#125;
        ];

        this.groupedCities = [
            &#123;
                label: 'Germany', value: 'de', 
                items: [
                    &#123;label: 'Berlin', value: 'Berlin'&#125;,
                    &#123;label: 'Frankfurt', value: 'Frankfurt'&#125;,
                    &#123;label: 'Hamburg', value: 'Hamburg'&#125;,
                    &#123;label: 'Munich', value: 'Munich'&#125;
                ]
            &#125;,
            &#123;
                label: 'USA', value: 'us', 
                items: [
                    &#123;label: 'Chicago', value: 'Chicago'&#125;,
                    &#123;label: 'Los Angeles', value: 'Los Angeles'&#125;,
                    &#123;label: 'New York', value: 'New York'&#125;,
                    &#123;label: 'San Francisco', value: 'San Francisco'&#125;
                ]
            &#125;,
            &#123;
                label: 'Japan', value: 'jp', 
                items: [
                    &#123;label: 'Kyoto', value: 'Kyoto'&#125;,
                    &#123;label: 'Osaka', value: 'Osaka'&#125;,
                    &#123;label: 'Tokyo', value: 'Tokyo'&#125;,
                    &#123;label: 'Yokohama', value: 'Yokohama'&#125;
                ]
            &#125;
        ];
    &#125;
    
&#125;
</app-code>

    </p-tabPanel>
    <p-tabPanel header="StackBlitz">
        <ng-template pTemplate="content">
            <iframe src="https://stackblitz.com/edit/primeng-listbox-demo?embed=1" style="width: 100%; height: 768px; border: none;"></iframe>
        </ng-template>
    </p-tabPanel>
  </p-tabView>
</div>

